package com.feng.chat.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.feng.chat.common.Common;
import com.feng.chat.dto.KeepAlive;
import com.feng.chat.dto.Result;
import com.feng.chat.entity.*;
import com.feng.chat.mapper.*;
import com.feng.chat.service.ITalkRecordsFileService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.feng.chat.utils.GetUserUtil;
import com.feng.chat.vo.EmoticonVO;
import com.feng.chat.vo.EventTalkDataVO;
import com.feng.chat.vo.EventTalkVO;
import com.feng.chat.vo.FileVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

/**
 * <p>
 * 用户聊天记录_文件消息表 服务实现类
 * </p>
 *
 * @author dyf
 * @since 2022-05-31
 */
@Service
public class TalkRecordsFileServiceImpl extends ServiceImpl<TalkRecordsFileMapper, TalkRecordsFile> implements ITalkRecordsFileService {
    @Autowired
    private TalkRecordsMapper talkRecordsMapper;

    @Autowired
    private EmoticonItemMapper emoticonItemMapper;

    @Autowired
    private UsersMapper usersMapper;

    @Autowired
    private GroupMemberMapper groupMemberMapper;

    @Autowired
    private TalkRecordsFileMapper talkRecordsFileMapper;

    @Autowired
    private SplitUploadMapper splitUploadMapper;

    /**
     * 发送表情消息
     * @param uid
     * @param emotionVO
     * @return
     */
    @Override
    public Result messageEmoticon(Integer uid, EmoticonVO emotionVO) {

        TalkRecords talkRecords = new TalkRecords();
        talkRecords.setMsgType(2);
        if (emotionVO.getTalk_type()==2){
            talkRecords.setGroupRead(uid.toString());
        }
        talkRecords.setReceiverId(emotionVO.getReceiver_id());
        talkRecords.setUserId(uid);
        talkRecords.setTalkType(emotionVO.getTalk_type());

        int insert = talkRecordsMapper.insert(talkRecords);

        EmoticonItem emoticonItem = emoticonItemMapper.selectById(emotionVO.getEmoticon_id());
        TalkRecordsFile talkRecordsFile = new TalkRecordsFile();
        talkRecordsFile.setRecordId(talkRecords.getId());
        talkRecordsFile.setDrive(1);
        talkRecordsFile.setOriginalName(emoticonItem.getRepresent());
        talkRecordsFile.setPath(emoticonItem.getUrl());
        talkRecordsFile.setSize(emoticonItem.getFileSize());
        talkRecordsFile.setSource(2);
        talkRecordsFile.setSuffix(emoticonItem.getFileSuffix());
        talkRecordsFile.setType(1);
        talkRecordsFile.setUrl(emoticonItem.getUrl());
        talkRecordsFile.setUserId(uid);
        boolean save = save(talkRecordsFile);

        KeepAlive keepAlive = new KeepAlive();
        keepAlive.setEvent(Common.EVENT_TALK);

        EventTalkVO eventTalkVO = new EventTalkVO();
        eventTalkVO.setTalk_type(emotionVO.getTalk_type());
        eventTalkVO.setSender_id(uid);
        eventTalkVO.setReceiver_id(emotionVO.getReceiver_id());

        Users users = usersMapper.selectById(uid);

        EventTalkDataVO eventTalkDataVO = new EventTalkDataVO();
        eventTalkDataVO.setAvatar(users.getAvatar());
        eventTalkDataVO.setCreated_at(talkRecords.getUpdatedAt().format(DateTimeFormatter.ofPattern(Common.LOCALDATETIME_FORMATER)));
        eventTalkDataVO.setId(talkRecords.getId());
        eventTalkDataVO.setIs_mark(talkRecords.getIsMark());
        eventTalkDataVO.setIs_read(talkRecords.getIsRead());
        eventTalkDataVO.setIs_revoke(talkRecords.getIsRevoke());
        eventTalkDataVO.setMsg_type(talkRecords.getMsgType());
        eventTalkDataVO.setNickname(users.getNickName());
        eventTalkDataVO.setReceiver_id(talkRecords.getReceiverId());
        eventTalkDataVO.setTalk_type(talkRecords.getTalkType());
        eventTalkDataVO.setUser_id(talkRecords.getUserId());

        FileVO fileVO = new FileVO();
        fileVO.setCreated_at(talkRecordsFile.getCreatedAt().format(DateTimeFormatter.ofPattern(Common.LOCALDATETIME_FORMATER)));
        fileVO.setDrive(talkRecordsFile.getDrive());
        fileVO.setId(talkRecordsFile.getId());
        fileVO.setOriginal_name(talkRecordsFile.getOriginalName());
        fileVO.setPath(talkRecordsFile.getPath());
        fileVO.setRecord_id(talkRecordsFile.getRecordId());
        fileVO.setSize(talkRecordsFile.getSize());
        fileVO.setSource(talkRecordsFile.getSource());
        fileVO.setSuffix(talkRecordsFile.getSuffix());
        fileVO.setType(talkRecordsFile.getType());
        fileVO.setUrl(talkRecordsFile.getUrl());
        fileVO.setUser_id(talkRecordsFile.getUserId());

        eventTalkDataVO.setFile(fileVO);
        eventTalkVO.setData(eventTalkDataVO);

        keepAlive.setContent(eventTalkVO);

        GetUserUtil.sendMessage(keepAlive, uid);
        if (emotionVO.getTalk_type()==1){
            if (GetUserUtil.isOnLine(emotionVO.getReceiver_id()) == 1) {
                GetUserUtil.sendMessage(keepAlive, emotionVO.getReceiver_id());
            }
        }else {
            List<Integer> groupMember = groupMemberMapper.getGroupMember(emotionVO.getReceiver_id());
            groupMember.remove(uid);
            for (Integer user_id : groupMember) {
                if (GetUserUtil.isOnLine(user_id) == 1) {
                    GetUserUtil.sendMessage(keepAlive, user_id);
                }
            }
        }


        return Result.success();
    }

    /**
     * 发送图片消息
     * @param uid
     * @param talk_type
     * @param receiver_id
     * @param image
     * @return
     */
    @Override
    public Result messageImage(Integer uid, Integer talk_type, Integer receiver_id, MultipartFile image) {
        TalkRecords talkRecords = new TalkRecords();
        talkRecords.setTalkType(talk_type);
        talkRecords.setMsgType(2);
        if (talk_type==2){
            talkRecords.setGroupRead(uid.toString());
        }
        talkRecords.setUserId(uid);
        talkRecords.setReceiverId(receiver_id);
        talkRecordsMapper.insert(talkRecords);

        String path="E:\\Desktop\\案例\\javaweb案例\\MyChat\\resource\\file\\";
        String oldFileName = image.getOriginalFilename();
        String suffix = oldFileName.substring(oldFileName.lastIndexOf(".") + 1);
        long size = image.getSize();
        String newFileName = UUID.randomUUID().toString().replaceAll("-", "");
        newFileName=newFileName+"."+suffix;
        String url="http://localhost:8081/file/"+newFileName;
        path=path+newFileName;
        File file = new File(path);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        try {
            image.transferTo(file);
        } catch (IOException e) {
            e.printStackTrace();
        }

        TalkRecordsFile talkRecordsFile = new TalkRecordsFile();
        talkRecordsFile.setRecordId(talkRecords.getId());
        talkRecordsFile.setUserId(talkRecords.getUserId());
        talkRecordsFile.setSource(1);
        talkRecordsFile.setType(1);
        talkRecordsFile.setDrive(1);
        talkRecordsFile.setOriginalName(oldFileName);
        talkRecordsFile.setSuffix(suffix);
        talkRecordsFile.setSize(size);
        talkRecordsFile.setPath(path);
        talkRecordsFile.setUrl(url);
        save(talkRecordsFile);

        KeepAlive keepAlive = new KeepAlive();
        keepAlive.setEvent(Common.EVENT_TALK);

        EventTalkVO eventTalkVO = new EventTalkVO();
        eventTalkVO.setSender_id(talkRecords.getUserId());
        eventTalkVO.setTalk_type(talkRecords.getTalkType());
        eventTalkVO.setReceiver_id(talkRecords.getReceiverId());

        EventTalkDataVO eventTalkDataVO = new EventTalkDataVO();
        eventTalkDataVO.setUser_id(talkRecords.getUserId());
        eventTalkDataVO.setTalk_type(talkRecords.getTalkType());
        eventTalkDataVO.setReceiver_id(talkRecords.getReceiverId());
        eventTalkDataVO.setMsg_type(talkRecords.getMsgType());
        eventTalkDataVO.setIs_revoke(talkRecords.getIsRevoke());
        eventTalkDataVO.setIs_read(talkRecords.getIsRead());
        eventTalkDataVO.setIs_mark(talkRecords.getIsMark());
        eventTalkDataVO.setId(talkRecords.getId());
        eventTalkDataVO.setCreated_at(talkRecords.getUpdatedAt().format(DateTimeFormatter.ofPattern(Common.LOCALDATETIME_FORMATER)));
        Users users = usersMapper.selectById(talkRecords.getUserId());
        eventTalkDataVO.setNickname(users.getNickName());
        eventTalkDataVO.setAvatar(users.getAvatar());

        FileVO fileVO = new FileVO();
        fileVO.setUser_id(talkRecordsFile.getUserId());
        fileVO.setUrl(talkRecordsFile.getUrl());
        fileVO.setType(talkRecordsFile.getType());
        fileVO.setSuffix(talkRecordsFile.getSuffix());
        fileVO.setSource(talkRecordsFile.getSource());
        fileVO.setSize(talkRecordsFile.getSize());
        fileVO.setRecord_id(talkRecordsFile.getRecordId());
        fileVO.setPath(talkRecordsFile.getPath());
        fileVO.setOriginal_name(talkRecordsFile.getOriginalName());
        fileVO.setId(talkRecordsFile.getId());
        fileVO.setDrive(talkRecordsFile.getDrive());
        fileVO.setCreated_at(talkRecordsFile.getCreatedAt().format(DateTimeFormatter.ofPattern(Common.LOCALDATETIME_FORMATER)));

        eventTalkDataVO.setFile(fileVO);
        eventTalkVO.setData(eventTalkDataVO);
        keepAlive.setContent(eventTalkVO);

        GetUserUtil.sendMessage(keepAlive, uid);
        if (talk_type == 1) {
            if (GetUserUtil.isOnLine(receiver_id) == 1) {
                GetUserUtil.sendMessage(keepAlive, receiver_id);
            }
        } else {
            List<Integer> groupMember = groupMemberMapper.getGroupMember(receiver_id);
            groupMember.remove(uid);
            for (Integer user_id : groupMember) {
                if (GetUserUtil.isOnLine(user_id) == 1) {
                    GetUserUtil.sendMessage(keepAlive, user_id);
                }
            }
        }

        return Result.success();
    }

    /**
     * 发送文件信息
     * @param uid
     * @param receiver_id
     * @param talk_type
     * @param upload_id
     * @return
     */
    @Override
    public Result messageFile(Integer uid, Integer receiver_id, Integer talk_type, String upload_id) {
        TalkRecords talkRecords = new TalkRecords();
        talkRecords.setTalkType(talk_type);
        talkRecords.setMsgType(2);
        if (talk_type==2){
            talkRecords.setGroupRead(uid.toString());
        }
        talkRecords.setUserId(uid);
        talkRecords.setReceiverId(receiver_id);
        talkRecordsMapper.insert(talkRecords);

        QueryWrapper<SplitUpload> splitUploadQueryWrapper = new QueryWrapper<>();
        splitUploadQueryWrapper.eq("upload_id", upload_id).eq("type", 1).eq("is_delete", 0).eq("user_id", uid);
        SplitUpload splitUpload = splitUploadMapper.selectOne(splitUploadQueryWrapper);

        TalkRecordsFile talkRecordsFile = new TalkRecordsFile();
        talkRecordsFile.setRecordId(talkRecords.getId());
        talkRecordsFile.setUserId(talkRecords.getUserId());
        talkRecordsFile.setSource(1);

        if (Arrays.asList(Common.AUDIO).contains(splitUpload.getFileExt())){
            talkRecordsFile.setType(2);
        }else if (Arrays.asList(Common.VIDEO).contains(splitUpload.getFileExt())){
            talkRecordsFile.setType(3);
        }else {
            talkRecordsFile.setType(4);
        }

        talkRecordsFile.setDrive(1);
        talkRecordsFile.setOriginalName(splitUpload.getOriginalName());
        talkRecordsFile.setSuffix(splitUpload.getFileExt());
        talkRecordsFile.setSize(splitUpload.getFileSize());
        talkRecordsFile.setPath(splitUpload.getPath());
        String url="http://localhost:8081/file/"+splitUpload.getOriginalName();
        talkRecordsFile.setUrl(url);

        talkRecordsFileMapper.insert(talkRecordsFile);

        KeepAlive keepAlive = new KeepAlive();
        keepAlive.setEvent(Common.EVENT_TALK);

        EventTalkVO eventTalkVO = new EventTalkVO();
        eventTalkVO.setSender_id(talkRecords.getUserId());
        eventTalkVO.setTalk_type(talkRecords.getTalkType());
        eventTalkVO.setReceiver_id(talkRecords.getReceiverId());

        EventTalkDataVO eventTalkDataVO = new EventTalkDataVO();
        eventTalkDataVO.setUser_id(talkRecords.getUserId());
        eventTalkDataVO.setTalk_type(talkRecords.getTalkType());
        eventTalkDataVO.setReceiver_id(talkRecords.getReceiverId());
        eventTalkDataVO.setMsg_type(talkRecords.getMsgType());
        eventTalkDataVO.setIs_revoke(talkRecords.getIsRevoke());
        eventTalkDataVO.setIs_read(talkRecords.getIsRead());
        eventTalkDataVO.setIs_mark(talkRecords.getIsMark());
        eventTalkDataVO.setId(talkRecords.getId());
        eventTalkDataVO.setCreated_at(talkRecords.getUpdatedAt().format(DateTimeFormatter.ofPattern(Common.LOCALDATETIME_FORMATER)));
        Users users = usersMapper.selectById(talkRecords.getUserId());
        eventTalkDataVO.setNickname(users.getNickName());
        eventTalkDataVO.setAvatar(users.getAvatar());

        FileVO fileVO = new FileVO();
        fileVO.setUser_id(talkRecordsFile.getUserId());
        fileVO.setUrl(talkRecordsFile.getUrl());
        fileVO.setType(talkRecordsFile.getType());
        fileVO.setSuffix(talkRecordsFile.getSuffix());
        fileVO.setSource(talkRecordsFile.getSource());
        fileVO.setSize(talkRecordsFile.getSize());
        fileVO.setRecord_id(talkRecordsFile.getRecordId());
        fileVO.setPath(talkRecordsFile.getPath());
        fileVO.setOriginal_name(talkRecordsFile.getOriginalName());
        fileVO.setId(talkRecordsFile.getId());
        fileVO.setDrive(talkRecordsFile.getDrive());
        fileVO.setCreated_at(talkRecordsFile.getCreatedAt().format(DateTimeFormatter.ofPattern(Common.LOCALDATETIME_FORMATER)));

        eventTalkDataVO.setFile(fileVO);
        eventTalkVO.setData(eventTalkDataVO);
        keepAlive.setContent(eventTalkVO);

        GetUserUtil.sendMessage(keepAlive, uid);
        if (talk_type == 1) {
            if (GetUserUtil.isOnLine(receiver_id) == 1) {
                GetUserUtil.sendMessage(keepAlive, receiver_id);
            }
        } else {
            List<Integer> groupMember = groupMemberMapper.getGroupMember(receiver_id);
            groupMember.remove(uid);
            for (Integer user_id : groupMember) {
                if (GetUserUtil.isOnLine(user_id) == 1) {
                    GetUserUtil.sendMessage(keepAlive, user_id);
                }
            }
        }

        return Result.success();
    }

    /**
     * 文件下载
     * @param response
     * @param cr_id
     */
    @Override
    public void fileDownload(HttpServletResponse response, Integer cr_id) {
        QueryWrapper<TalkRecordsFile> talkRecordsFileQueryWrapper = new QueryWrapper<>();
        talkRecordsFileQueryWrapper.eq("record_id",cr_id).eq("is_delete",0);
        TalkRecordsFile talkRecordsFile = talkRecordsFileMapper.selectOne(talkRecordsFileQueryWrapper);

        File file = new File(talkRecordsFile.getPath());
        InputStream inputStream = null;
        try {
            inputStream = new FileInputStream(file);
            response.reset();
            response.setContentType("application/octet-stream");
            String filename = talkRecordsFile.getOriginalName();
            response.addHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(filename, "UTF-8"));
            ServletOutputStream outputStream = response.getOutputStream();
            byte[] b = new byte[1024];
            int len;
            //从输入流中读取一定数量的字节，并将其存储在缓冲区字节数组中，读到末尾返回-1
            while ((len = inputStream.read(b)) > 0) {
                outputStream.write(b, 0, len);
            }
            inputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
